import java.io.ByteArrayInputStream;
import java.net.UnknownHostException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.herohead.CDLogger;
import com.herohead.Rabbitmq;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.GetResponse;

public class updateBackupTotals {

	private static org.apache.log4j.Logger log= Logger.getLogger(updateBackupTotals.class);

	public static PreparedStatement check;
	public static PreparedStatement upsertStatement;
	public static Connection connect = null;
	public static Statement statement = null;
	public static String checkForRecord = null;
	public static String xmlSourceSystem = null;
	public static String sqlString = null;
	public static String SQLConnection = null;
	public static String backupLogTotalsTable = null;

	/**
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub


		final CDLogger cdlog = new CDLogger();

		Runtime.getRuntime().addShutdownHook(new Thread() {
			public void run() { 
				cdlog.programStop(log);
			}
		});

		cdlog.programStart(log);

		String className = "updateBackupTotals";
		PropertiesConfiguration config = new PropertiesConfiguration(className + ".config");
		log.debug("reading config file");

		String rabbitmqserver = config.getString("rabbitmqserver");
		String RMQQueue = config.getString("RMQQueue");
		String RMQVirtualHost= config.getString("RMQVirtualHost"); 
		String RMQUsername= config.getString("RMQUsername");
		String RMQPassword= config.getString("RMQPassword");
		SQLConnection= config.getString("SQLConnection");

		/*
		 *  backupLogTotalsTable=backup.backuplogtotals
		 */
		backupLogTotalsTable = config.getString("backupLogTotalsTable");


		log.debug("Connection to RabbitMQ server");

		Rabbitmq rmq = new Rabbitmq();
		rmq.setHostname(rabbitmqserver);
		rmq.setLogin(RMQVirtualHost, RMQPassword, RMQUsername);
		//log.info("Connecting to " + rabbitmqserver);
		rmq.setupChannel();
		rmq.setQueue(RMQQueue);

		rmq.declareQueDurable();
		Channel channel = rmq.getChannel();

		sqlString = "insert into " + backupLogTotalsTable +
				" (timestamp,sourceSystem,count,type) values (?,?,?,?)";


		connect = DriverManager.getConnection(SQLConnection);	

		statement = connect.createStatement();

		//check = connect.prepareStatement(checkForRecord);

		channel = rmq.getChannel();

		log.debug("Waiting for message");
		//System.out.println("Waiting for message");
		String message = null;
		long deliveryTag;

		boolean autoAck = false;
		//GetResponse response = channel.basicGet(RMQQueue, autoAck);
		GetResponse response = null;
		@SuppressWarnings("unused")
		AMQP.BasicProperties props;
		do {
			response = channel.basicGet(RMQQueue, autoAck);
			if (response == null) {
				break;
			} else {
				props = response.getProps();
				// byte[] body = response.getBody();
				message = new String(response.getBody());
				deliveryTag = response.getEnvelope().getDeliveryTag();
				readXML(message);
				//channel.basicAck(response.getEnvelope().getDeliveryTag(), true);
				channel.basicAck(deliveryTag, false);
			}
		} while (true);

		close();

		System.exit(0);
	}
	private static void close() {
		try {
			if (check != null) {
				check.close();
			}
			if (upsertStatement != null) {
				upsertStatement.close();
			}
			if (statement != null) {
				statement.close();
			}
			if (connect != null) {
				connect.close();
			}
		} catch (Exception e) {
		}
	}

	public static void readXML(String emailXml) throws Exception {

		String xmlTimeStamp = null;
		String xmlCount = null;
		String xmlType = null;

		try {
			DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
			Document doc = dBuilder.parse(new ByteArrayInputStream(emailXml.getBytes("UTF-8")));
			doc.getDocumentElement().normalize();

			NodeList nList = doc.getElementsByTagName("totals_log");
			for (int temp = 0; temp < nList.getLength(); temp++) {
				Node nNode = nList.item(temp);
				if (nNode.getNodeType() == Node.ELEMENT_NODE) {
					Element eElement = (Element) nNode;
					xmlTimeStamp = checkNull(eElement.getElementsByTagName("timestamp").item(0).getTextContent(),true);
					xmlSourceSystem = checkNull(eElement.getElementsByTagName("sourceSystem").item(0).getTextContent(),true);
					xmlCount = checkNull(eElement.getElementsByTagName("count").item(0).getTextContent(),false);
					xmlType = checkNull(eElement.getElementsByTagName("type").item(0).getTextContent(),false);
				}
				dBuilder.reset();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		upSertLog( xmlTimeStamp, xmlSourceSystem,xmlCount ,xmlType);
	}
	public static String checkNull(String s,boolean str) {
		if (s.length() == 0) 
			if (str) s = null;
			else s = "0";
		return s;
	}
	public static void upSertLog(String timestamp,String sourceSystem,String count,String type) throws SQLException, Exception {

		upsertStatement = connect.prepareStatement(sqlString);
		upsertStatement.setString(1, timestamp);
		upsertStatement.setString(2, sourceSystem);
		upsertStatement.setString(3, count);
		upsertStatement.setString(4, type);
		log.debug(" Adding to table : " + sourceSystem + " " +  sourceSystem + " " + type);
		upsertStatement.execute();
	} 

}
